from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, Body, Query
from sqlalchemy.orm import Session, joinedload
from app.database import get_db
from app.models import User, Spot, Order
from app.core.auth import get_current_user
from typing import List
import shutil
import os
from pydantic import BaseModel

router = APIRouter()

# 验证是否是管理员的依赖函数
def get_current_admin(current_user: User = Depends(get_current_user)):
    if current_user.role != "admin":
        raise HTTPException(status_code=403, detail="需要管理员权限")
    return current_user

# 景点管理
@router.get("/spots")
def get_all_spots(
    db: Session = Depends(get_db),
    admin: User = Depends(get_current_admin)
):
    """获取所有景点列表"""
    spots = db.query(Spot).all()
    return spots

class SpotCreate(BaseModel):
    name: str
    description: str
    location: str
    type: str
    open_time: str
    price: float
    inventory: int

@router.post("/spots")
async def create_spot(
    name: str = Form(...),
    description: str = Form(...),
    location: str = Form(...),
    type: str = Form(...),
    open_time: str = Form(...),
    price: float = Form(...),
    inventory: int = Form(...),
    image: UploadFile = File(...),
    db: Session = Depends(get_db),
    admin: User = Depends(get_current_admin)
):
    """创建新景点"""
    try:
        # 处理图片上传
        filename = f"{name}-{image.filename}"
        # 保存到前端的 public/images/spots 目录
        save_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))), 
                                "public", "images", "spots")
        os.makedirs(save_path, exist_ok=True)
        
        file_path = os.path.join(save_path, filename)
        
        with open(file_path, "wb") as buffer:
            shutil.copyfileobj(image.file, buffer)
        
        # 创建景点
        spot = Spot(
            name=name,
            description=description,
            location=location,
            type=type,
            open_time=open_time,
            price=price,
            inventory=inventory,
            images=f"/images/spots/{filename}",  # 使用相对于前端的路径
            rating=0
        )
        db.add(spot)
        db.commit()
        db.refresh(spot)
        return spot
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.put("/spots/{spot_id}")
async def update_spot(
    spot_id: int,
    name: str = Form(...),
    description: str = Form(...),
    location: str = Form(...),
    type: str = Form(...),
    open_time: str = Form(...),
    price: float = Form(...),
    inventory: int = Form(...),
    image: UploadFile | None = None,
    db: Session = Depends(get_db),
    admin: User = Depends(get_current_admin)
):
    """更新景点信息"""
    spot = db.query(Spot).filter(Spot.id == spot_id).first()
    if not spot:
        raise HTTPException(status_code=404, detail="景点不存在")
    
    try:
        # 如果有新图片，处理图片上传
        if image:
            filename = f"spots/{name}-{image.filename}"
            os.makedirs("../public/images/spots", exist_ok=True)
            file_path = f"../public/images/{filename}"
            
            with open(file_path, "wb") as buffer:
                shutil.copyfileobj(image.file, buffer)
            
            spot.images = f"/images/{filename}"
        
        # 更新其他字段
        spot.name = name
        spot.description = description
        spot.location = location
        spot.type = type
        spot.open_time = open_time
        spot.price = price
        spot.inventory = inventory
        
        db.commit()
        db.refresh(spot)
        return spot
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.delete("/spots/{spot_id}")
def delete_spot(
    spot_id: int,
    db: Session = Depends(get_db),
    admin: User = Depends(get_current_admin)
):
    """删除景点"""
    spot = db.query(Spot).filter(Spot.id == spot_id).first()
    if not spot:
        raise HTTPException(status_code=404, detail="景点不存在")
    
    db.delete(spot)
    db.commit()
    return {"message": "景点已删除"}

# 用户管理
@router.get("/users")
def get_all_users(
    db: Session = Depends(get_db),
    admin: User = Depends(get_current_admin)
):
    """获取所有用户列表"""
    users = db.query(User).all()
    return users

@router.put("/users/{user_id}")
def update_user(
    user_id: int,
    user_data: dict,
    db: Session = Depends(get_db),
    admin: User = Depends(get_current_admin)
):
    """更新用户信息"""
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    for key, value in user_data.items():
        if key != "password":  # 不直接更新密码
            setattr(user, key, value)
    
    db.commit()
    db.refresh(user)
    return user

@router.put("/users/{user_id}/role")
def update_user_role(
    user_id: int,
    role: str,
    db: Session = Depends(get_db),
    admin: User = Depends(get_current_admin)
):
    """更新用户角色"""
    if role not in ['user', 'admin']:
        raise HTTPException(status_code=400, detail="无效的角色")
    
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    user.role = role
    db.commit()
    return {"message": "角色更新成功"}

# 添加请求体模型
class UserStatusUpdate(BaseModel):
    is_active: bool

@router.put("/users/{user_id}/status")
def update_user_status(
    user_id: int,
    status_update: UserStatusUpdate,  # 使用 Pydantic 模型接收请求体
    db: Session = Depends(get_db),
    admin: User = Depends(get_current_admin)
):
    """禁用/启用用户"""
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    # 防止禁用管理员账户
    if user.role == 'admin':
        raise HTTPException(status_code=400, detail="不能禁用管理员账户")
    
    user.is_active = status_update.is_active  # 使用模型中的值
    db.commit()
    return {"message": "状态更新成功"}

# 订单管理
@router.get("/orders")
def get_all_orders(
    page: int = Query(1, ge=1),  # 页码,默认第1页,必须大于等于1
    page_size: int = Query(10, ge=1, le=100),  # 每页数量,默认10条,1-100之间
    db: Session = Depends(get_db),
    admin: User = Depends(get_current_admin)
):
    """获取所有订单"""
    # 计算总数
    total = db.query(Order).count()
    
    # 获取分页数据
    orders = (
        db.query(Order)
        .join(User)
        .join(Spot)
        .options(
            joinedload(Order.user),
            joinedload(Order.spot)
        )
        .order_by(Order.created_at.desc())
        .offset((page - 1) * page_size)  # 计算偏移量
        .limit(page_size)  # 限制返回数量
        .all()
    )
    
    return {
        "total": total,  # 总记录数
        "page": page,    # 当前页码
        "page_size": page_size,  # 每页数量
        "total_pages": (total + page_size - 1) // page_size,  # 总页数
        "items": [
            {
                "id": order.id,
                "user_id": order.user_id,
                "spot_id": order.spot_id,
                "quantity": order.quantity,
                "total_price": order.total_price,
                "status": order.status,
                "visit_date": order.visit_date,
                "created_at": order.created_at,
                "contact_name": order.contact_name,
                "contact_phone": order.contact_phone,
                "rating": order.rating,
                "user": {
                    "id": order.user.id,
                    "username": order.user.username,
                    "email": order.user.email
                },
                "spot": {
                    "id": order.spot.id,
                    "name": order.spot.name,
                    "price": order.spot.price
                }
            }
            for order in orders
        ]
    }

@router.put("/orders/{order_id}")
def update_order(
    order_id: int,
    order_data: dict,
    db: Session = Depends(get_db),
    admin: User = Depends(get_current_admin)
):
    """更新订单状态"""
    order = db.query(Order).filter(Order.id == order_id).first()
    if not order:
        raise HTTPException(status_code=404, detail="订单不存在")
    
    for key, value in order_data.items():
        setattr(order, key, value)
    
    db.commit()
    db.refresh(order)
    return order

# 数据统计
@router.get("/statistics")
def get_statistics(
    db: Session = Depends(get_db),
    admin: User = Depends(get_current_admin)
):
    """获取统计数据"""
    total_users = db.query(User).count()
    total_orders = db.query(Order).count()
    total_spots = db.query(Spot).count()
    
    return {
        "total_users": total_users,
        "total_orders": total_orders,
        "total_spots": total_spots
    }

@router.post("/upload")
async def upload_file(
    file: UploadFile = File(...),
    filename: str = Form(...),
    admin: User = Depends(get_current_admin)
):
    """上传文件"""
    try:
        # 确保目录存在
        os.makedirs("../public/images/spots", exist_ok=True)
        
        # 保存文件
        file_path = f"../public/images/spots/{os.path.basename(filename)}"
        with open(file_path, "wb") as buffer:
            shutil.copyfileobj(file.file, buffer)
        
        return {"message": "文件上传成功"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"文件上传失败: {str(e)}") 